package com.example.auth.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.auth.common.R;
import com.example.auth.model.dto.LoginDTO;
import com.example.auth.model.dto.UserAddDTO;
import com.example.auth.model.dto.UserInfoDTO;
import com.example.auth.model.dto.UserUpdateDTO;
import com.example.auth.model.entity.SysDepartment;
import com.example.auth.model.entity.SysRole;
import com.example.auth.model.entity.SysUser;
import com.example.auth.mapper.SysDepartmentMapper;
import com.example.auth.mapper.SysRoleMapper;
import com.example.auth.mapper.SysUserMapper;
import com.example.auth.mapper.SysUserRoleMapper;
import com.example.auth.model.entity.SysUserRole;
import com.example.auth.model.vo.SysUserVo;
import com.example.auth.service.SysDepartmentService;
import com.example.auth.service.SysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import jakarta.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysDepartmentMapper departmentMapper;
    
    @Resource
    private SysRoleMapper roleMapper;
    
    @Resource
    private SysUserRoleMapper userRoleMapper;
    
    @Resource
    private SysDepartmentService departmentService;

    /**
     * 用户登录
     *
     * @param loginDTO 登录信息
     * @return 登录结果
     */
    @Override
    public R<String> login(LoginDTO loginDTO) {
        // 根据用户名查询用户
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername, loginDTO.getUsername());
        SysUser user = getOne(queryWrapper);

        // 用户不存在或已被删除
        if (user == null || user.getIsDeleted() == 1) {
            return R.failed("用户名或密码错误");
        }

        // 账号被禁用
        if (user.getStatus() == 0) {
            return R.failed("账号已被禁用");
        }

        // 密码校验
        if (!loginDTO.getPassword().equals(user.getPassword())) {
            return R.failed("用户名或密码错误");
        }

        // 登录成功，使用Sa-Token记录登录状态
        StpUtil.login(user.getId());
        
        // 返回token
        return R.ok(StpUtil.getTokenValue());
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 用户信息
     */
    @Override
    public R<UserInfoDTO> getCurrentUserInfo() {
        // 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 根据ID查询用户
        SysUser user = getById(userId);
        if (user == null) {
            return R.failed("用户不存在");
        }
        
        // 构建用户信息DTO
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        BeanUtils.copyProperties(user, userInfoDTO);
        
        // 获取用户角色列表
        List<String> roles = baseMapper.selectRoleCodesByUserId(userId);
        userInfoDTO.setRoles(roles);
        
        // 获取用户权限列表
        List<String> permissions = baseMapper.selectPermissionsByUserId(userId);
        userInfoDTO.setPermissions(permissions);
        
        // 获取部门信息
        if (user.getDepartmentId() != null) {
            SysDepartment department = departmentMapper.selectById(user.getDepartmentId());
            if (department != null) {
                userInfoDTO.setDepartmentName(department.getName());
            }
        }
        
        return R.ok(userInfoDTO);
    }

    /**
     * 用户退出登录
     */
    @Override
    public void logout() {
        StpUtil.logout();
    }

    /**
     * 根据用户ID获取用户角色列表
     *
     * @param userId 用户ID
     * @return 角色编码列表
     */
    @Override
    public String[] getUserRoles(Long userId) {
        List<String> roles = baseMapper.selectRoleCodesByUserId(userId);
        return roles.toArray(new String[0]);
    }
    
    /**
     * 获取用户列表（分页）
     *
     * @param current   当前页
     * @param size      每页大小
     * @param username  用户名
     * @param nickname  昵称
     * @param phone     手机号
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 用户分页列表
     */
    @Override
    public Page<SysUser> getUserPage(Integer current, Integer size, String username, String nickname, String phone, String startDate, String endDate) {
        Page<SysUser> page = new Page<>(current, size);
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        queryWrapper.like(StringUtils.hasText(username), SysUser::getUsername, username)
                .like(StringUtils.hasText(nickname), SysUser::getNickname, nickname)
                .like(StringUtils.hasText(phone), SysUser::getPhone, phone);
        
        // 处理日期范围查询
        if (StringUtils.hasText(startDate) && StringUtils.hasText(endDate)) {
            LocalDateTime startDateTime = LocalDate.parse(startDate).atStartOfDay();
            LocalDateTime endDateTime = LocalDate.parse(endDate).atTime(LocalTime.MAX);
            queryWrapper.between(SysUser::getCreateTime, startDateTime, endDateTime);
        }
        
        // 设置查询不包含已删除的数据
        queryWrapper.eq(SysUser::getIsDeleted, 0);
        
        // 按创建时间降序排序
        queryWrapper.orderByDesc(SysUser::getCreateTime);
        
        // 执行分页查询
        return page(page, queryWrapper);
    }
    
    /**
     * 根据部门ID获取用户列表
     *
     * @param departmentId 部门ID
     * @return 用户列表
     */
    @Override
    public List<SysUser> getUsersByDeptId(Long departmentId) {
        // 获取指定部门及其所有子部门ID
        List<SysDepartment> departments = departmentService.getDepartmentWithChildren(departmentId);
        List<Long> deptIds = departments.stream().map(SysDepartment::getId).collect(Collectors.toList());
        
        // 查询这些部门下的所有用户
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysUser::getDepartmentId, deptIds);
        queryWrapper.eq(SysUser::getIsDeleted, 0);
        
        return list(queryWrapper);
    }
    
    /**
     * 获取用户详情
     *
     * @param id 用户ID
     * @return 用户VO
     */
    @Override
    public SysUserVo getUserVoById(Long id) {
        // 获取用户基本信息
        SysUser user = getById(id);
        if (user == null) {
            return null;
        }
        
        // 构建返回VO
        SysUserVo userVo = new SysUserVo();
        BeanUtils.copyProperties(user, userVo);
        
        // 设置用户姓名
        userVo.setName(user.getNickname());
        
        // 获取部门信息
        if (user.getDepartmentId() != null) {
            SysDepartment department = departmentMapper.selectById(user.getDepartmentId());
            if (department != null) {
                userVo.setDepartment(department.getName());
            }
        }
        
        // 获取用户角色
        userVo.setRoles(getUserRoles(id));
        
        return userVo;
    }
    
    /**
     * 添加用户
     *
     * @param userDTO 用户DTO
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean addUser(UserAddDTO userDTO) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername, userDTO.getUsername());
        if (count(queryWrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建用户实体
        SysUser user = new SysUser();
        user.setUsername(userDTO.getUsername());
        user.setPassword(userDTO.getPassword());
        user.setNickname(userDTO.getName());
        user.setEmail(userDTO.getEmail());
        user.setPhone(userDTO.getPhone());
        user.setDepartmentId(userDTO.getDepartmentId());
        user.setStatus(userDTO.getStatus());
        
        // 保存用户
        return save(user);
    }
    
    /**
     * 更新用户
     *
     * @param userDTO 用户DTO
     * @return 是否成功
     */
    @Override
    public boolean updateUser(UserUpdateDTO userDTO) {
        // 检查用户是否存在
        SysUser user = getById(userDTO.getId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 更新用户信息
        user.setNickname(userDTO.getName());
        user.setEmail(userDTO.getEmail());
        user.setPhone(userDTO.getPhone());
        user.setDepartmentId(userDTO.getDepartmentId());
        user.setStatus(userDTO.getStatus());
        
        // 保存更新
        return updateById(user);
    }
    
    /**
     * 重置用户密码
     *
     * @param userId 用户ID
     * @return 是否成功
     */
    @Override
    public boolean resetPassword(Long userId) {
        // 检查用户是否存在
        SysUser user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 重置密码为123456
        user.setPassword("123456");
        
        // 保存更新
        return updateById(user);
    }
    
    /**
     * 更新用户状态
     *
     * @param userId 用户ID
     * @param status 状态
     * @return 是否成功
     */
    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        // 检查用户是否存在
        SysUser user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 更新用户状态
        user.setStatus(status);
        
        // 保存更新
        return updateById(user);
    }
    
    /**
     * 分配用户角色
     *
     * @param userId  用户ID
     * @param roleIds 角色ID列表
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean assignRoles(Long userId, List<Long> roleIds) {
        // 检查用户是否存在
        SysUser user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 先删除该用户所有角色
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId, userId);
        userRoleMapper.delete(wrapper);
        
        // 如果角色ID列表为空，表示清空用户角色
        if (roleIds == null || roleIds.isEmpty()) {
            return true;
        }
        
        // 重新分配角色
        List<SysUserRole> userRoles = new ArrayList<>();
        for (Long roleId : roleIds) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoles.add(userRole);
        }
        
        // 批量保存用户角色关系
        return userRoleMapper.insertBatch(userRoles);
    }
    
    /**
     * 获取用户角色ID列表
     *
     * @param userId 用户ID
     * @return 角色ID列表
     */
    @Override
    public List<Long> getUserRoleIds(Long userId) {
        // 查询用户角色关系
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId, userId);
        List<SysUserRole> userRoles = userRoleMapper.selectList(wrapper);
        
        // 提取角色ID
        return userRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
    }
}
